package personnel.department.pages;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.tuple.MutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.resource.FontRegistry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DateTime;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.forms.events.ExpansionAdapter;
import org.eclipse.ui.forms.events.ExpansionEvent;
import org.eclipse.ui.forms.events.IExpansionListener;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;

import personnel.department.pages.widgets.AbstractWidget;
import personnel.department.pages.widgets.CheckedWidget;
import personnel.department.pages.widgets.DateWidget;
import personnel.department.pages.widgets.LongWidget;
import personnel.department.pages.widgets.NumberWidget;
import personnel.department.pages.widgets.TextWidget;
import personnel.department.pages.widgets.combo.AbstractComboWidget;
import personnel.department.pages.widgets.combo.ComboWidgetFactory;
import personnel.department.utils.TranslatorUtils;

public class ColumnContent {

	private static List<Section> sections = Lists.newArrayList();
	private Composite column;
	private List<Field> fields;
	private final List<Pair<String, AbstractWidget<?>>> widgetByName = Lists.newArrayList();
	private final Map<Field, AbstractWidget<?>> widgetByField = Maps.newHashMap();
	private boolean withSection;


	public ColumnContent(Composite column, List<Field> fields) {
		this.column = column;
		this.fields = fields;
	}

	public ColumnContent(Composite column, List<Field> fields, boolean withSection) {
		this(column, fields);
		this.withSection = withSection;

	}

	public void createContent() {
		Multimap<String, Field> content = new SearchContent(fields).getContent();
		FormToolkit toolkit = new FormToolkit(column.getDisplay());
		Section section = null;
		Composite parent = column;
		for (String title : content.keySet()) {
			if (withSection) {
				section = new Section(column, Section.LEFT_TEXT_CLIENT_ALIGNMENT | Section.TWISTIE);
				sections.add(section);

				section.addExpansionListener(new IExpansionListener() {

					@Override
					public void expansionStateChanging(ExpansionEvent e) {
						// TODO Auto-generated method stub

					}

					@Override
					public void expansionStateChanged(ExpansionEvent e) {
						//					TwoColumnFieldsComposite parent = (TwoColumnFieldsComposite) column.getParent();
						//					parent.getLeftColumn().pack();
						//					parent.getRightColumn().pack();
						ScrolledComposite sc = (ScrolledComposite) column.getParent().getParent();
						sc.setMinSize(column.computeSize(SWT.DEFAULT, SWT.DEFAULT));
						//					parent.layout();
						sc.redraw();
					}
				});

				//для scrolledComposite чтобы установить размер

				section.setText(title);
				parent = section;
			}
			Composite clientComposite = createPropertyContent(content, title, parent);
			if (withSection) {
				toolkit.paintBordersFor(clientComposite);
				section.setClient(clientComposite);
			}
		}
	}

	private Composite createPropertyContent(Multimap<String, Field> content, String title,
			Composite parent) {
		Composite clientComposite = new Composite(parent, SWT.NONE);
		clientComposite.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
		clientComposite.setLayout(new GridLayout(2, true));
		
		if (!withSection) {
			Label labelTitle = new Label(clientComposite, SWT.NONE);
			labelTitle.setText(title);
			labelTitle.setLayoutData(GridDataFactory.swtDefaults().span(2, 1).create());
		}
		
	
		for (Field field : content.get(title)) {
			String fieldname = TranslatorUtils.fieldsTranslator.get(field.getName());
			
			if (TranslatorUtils.titleForCombo.contains(title)) {
				AbstractComboWidget comboWidget = ComboWidgetFactory.getComboWidget(clientComposite, fieldname, field);
				getWidgetByName().add(new MutablePair<String, AbstractWidget<?>>(fieldname, comboWidget));
				getWidgetByField().put(field, comboWidget);
				continue;
			}
			
			//TODO add other types and set with all widgets
			if (field.getType().equals(String.class)) {
				TextWidget text = new TextWidget(clientComposite, fieldname, field);
				getWidgetByName().add(new MutablePair<String, AbstractWidget<?>>(fieldname, text));
				getWidgetByField().put(field, text);
			} else if (field.getType().equals(Boolean.class)) {
				CheckedWidget check = new CheckedWidget(clientComposite, fieldname, field);
				getWidgetByName().add(new MutablePair<String, AbstractWidget<?>>(fieldname, check));
				getWidgetByField().put(field, check);
			} else if (field.getType().equals(Integer.class)) {
				NumberWidget number = new NumberWidget(clientComposite, fieldname, field);
				getWidgetByName().add(new MutablePair<String, AbstractWidget<?>>(fieldname, number));
				getWidgetByField().put(field, number);
			} else if (field.getType().equals(Long.class)) {
				LongWidget number = new LongWidget(clientComposite, fieldname, field);
				getWidgetByName().add(new MutablePair<String, AbstractWidget<?>>(fieldname, number));
				getWidgetByField().put(field, number);
			
			} else if (field.getType().equals(Date.class)) {
				DateWidget date = new DateWidget(clientComposite, fieldname, field);
				getWidgetByName().add(new MutablePair<String, AbstractWidget<?>>(fieldname, date));
				getWidgetByField().put(field, date);

			}
		}
		return clientComposite;
	}

	public void setSectionExpanded(boolean expanded) {
		sections.stream().forEach(section -> section.setExpanded(expanded));
	}

	public Map<Field, AbstractWidget<?>> getWidgetByField() {
		return widgetByField;
	}

	public List<Pair<String, AbstractWidget<?>>> getWidgetByName() {
		return widgetByName;
	}
}
